//
//  BSLCordovaViewController.m
//  bsl-sdk
//
//  Created by Fanty on 13-11-28.
//
//

#import "BSLWebViewController.h"

NSString *const BSLWebViewLoadingNotification = @"BSLWebViewLoadingNotification";
NSString *const BSLWebViewDidLoadNotification = @"BSLWebViewDidLoadNotification";
NSString *const BSLWebViewDidFailLoadNotification = @"BSLWebViewDidFailLoadNotification";
NSString *const BSLWebViewDidRefreshNotification = @"BSLWebViewDidRefreshNotification";

#define MAXPULLDISTANCE_DEFAULT 150
#define OFFSET_Y_OVER_DEFAULT 100
#define REFRESHING_HEIGHT_DEFAULT 60

#define REFRESH_DURATION_DEFAULT 0.4

@interface MyScrollView : UIScrollView

@property (nonatomic, assign) BOOL shouldSetOffset;//是否修改contentoffset
@property (nonatomic, assign) CGFloat maxPullDistance;//下拉最大距离
@property (nonatomic, assign) CGFloat refreshingHeight;//下拉刷新回滚到这个高度

@property (nonatomic, weak) UILabel *label;
@property (nonatomic, strong) NSString *contentDown;
@property (nonatomic, strong) NSString *contentOver;
@property (nonatomic, strong) NSString *contentRefresh;

@end

@implementation MyScrollView

- (id)initWithWebView:(UIWebView *)webView{
    self = [super init];
    if (self) {
        [self setFrame:webView.bounds];
        [self setContentSize:webView.scrollView.contentSize];
        [self setScrollsToTop:webView.scrollView.scrollsToTop];
        [self setBackgroundColor:webView.scrollView.backgroundColor];
        _shouldSetOffset = YES;
        _maxPullDistance = MAXPULLDISTANCE_DEFAULT;
        _refreshingHeight = REFRESHING_HEIGHT_DEFAULT;
        _contentDown = @"下拉可以刷新";
        _contentOver = @"释放立即刷新";
        _contentRefresh = @"正在刷新...";
        
        webView.scrollView.scrollEnabled = NO;
        //滚动效果在滚动中，在webview和MyScrollView中切换
    }
    
    return self;
}

- (void)setContentOffset:(CGPoint)contentOffset{
    //在滑动范围内才赋值,且当试图离开界面顶部时，滚动由MyScrollView实现
    if (self.shouldSetOffset && contentOffset.y > -self.maxPullDistance && contentOffset.y<=0) {
        [super setContentOffset:contentOffset];
    }
}

/**
 *  设置下拉时显示的控件，这里先用UILabel测试
 */
- (void)setupPullContent{
    if (!self.label) {
        UILabel *label = [[UILabel alloc] init];
        label.width = self.width;
        label.left = 0;
        label.height = 20;
        label.bottom = -10;
        [label setTextAlignment:NSTextAlignmentCenter];
        [self addSubview:label];
        self.label = label;
    }
}

@end

@interface BSLWebViewController (){
    CGFloat _screenWidth;
    CGFloat _screenHeight;
}

@property (nonatomic, assign) BOOL shouldLoad;
@property (nonatomic, assign) BOOL isLoading;
@property (nonatomic, weak) MyScrollView *pullScro;

@end

@implementation BSLWebViewController

-(id)init{
    self=[super init];
    
    if(self){
        if([[[UIDevice currentDevice] systemVersion] floatValue]>=7){
            self.edgesForExtendedLayout = UIRectEdgeNone;
            self.extendedLayoutIncludesOpaqueBars = NO;
            self.modalPresentationCapturesStatusBarAppearance = NO;
        }
        [self createGapView];
        
        _screenHeight = [UIScreen mainScreen].bounds.size.height;
        _screenWidth = [UIScreen mainScreen].bounds.size.width;
    }
    return self;
}

- (void)viewDidLoad{
    [self.view setBackgroundColor:[UIColor clearColor]];
    [self.view addSubview:self.webView];
    [self.view sendSubviewToBack:self.webView];
    [self loadFilePageWithFileUrl:self.URL];
    [super viewDidLoad];
    
//    for(UIView* view in self.webView.subviews){
//        if([view isKindOfClass:[UIScrollView class]]){
//            UIScrollView* scrollView=(UIScrollView*)view;
//            scrollView.showsHorizontalScrollIndicator=NO;
//            scrollView.showsVerticalScrollIndicator=NO;
//            scrollView.bounces=NO;
//            break;
//        }
//    }
}

- (void)createGapView{
    if (!self.webView) {
//        [super createGapView];
        CGRect webViewBounds = [UIScreen mainScreen].bounds;
        
        self.webView = [[BSLWebView alloc] initWithFrame:webViewBounds];
        self.webView.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
        self.webView.scrollView.delegate = self;
    }
}

- (void)didReceiveMemoryWarning{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

-(void)loadFilePageWithFileUrl:(NSURL*)fileUrl{
    [[NSURLCache sharedURLCache] removeAllCachedResponses];
    self.startPage = [fileUrl absoluteString];
}

-(UIStatusBarStyle)preferredStatusBarStyle{
    return UIStatusBarStyleLightContent;
}

/**
 *  消除视图手势和回弹效果，避免与父视图冲突
 */
- (void)cancelWebViewStyleWhenAppended{
    BSLWebView *webView = (BSLWebView *)self.webView;
    [webView.scrollView setBounces:NO];
    [webView setPopGesture:@"none"];
}

- (void)addChildViewController:(UIViewController *)childController{
    //将子视图的controller添加到父视图controller的ChildViewController
    BSLWebViewController *child = (BSLWebViewController *)childController;
    [child cancelWebViewStyleWhenAppended];
    
    [super addChildViewController:childController];
}

- (void)setStyle:(NSDictionary *)style{
    [(BSLWebView *)self.webView setStyle:style];
    [self.view setFrame:self.webView.frame];
    [self.webView setFrame:self.view.bounds];
}

- (void)setID:(NSString *)ID{
    [(BSLWebView *)self.webView setViewID:ID];
}

- (void)setURL:(NSString *)URLStr{
    NSURL *url = nil;
    if (![URLStr hasPrefix:@"http"]) {
        //本地路径
        NSString *path = [[NSBundle mainBundle] bundlePath];
        path = [path stringByAppendingPathComponent:URLStr];
        url = [NSURL fileURLWithPath:path];
    }
    
    else{
        url = [NSURL URLWithString:URLStr];
    }
    
    [(BSLWebView *)self.webView setViewURL:url];
}

- (NSString *)ID{
    NSString *Id = ((BSLWebView *)self.webView).viewID;
    if (!Id.length) {
        return nil;
    }
    
    return Id;
}

- (NSURL *)URL{
    return ((BSLWebView *)self.webView).viewURL;
}

- (void)loadUrl:(NSString *)urlStr{
    [self setURL:urlStr];
    NSURL *url = ((BSLWebView *)self.webView).viewURL;
    NSURLRequest *req = [NSURLRequest requestWithURL:url];
    [self.webView loadRequest:req];
}

- (void)goBack{
    [self.webView goBack];
}

- (BOOL)canBack{
    return self.webView.canGoBack;
}

- (void)goForward{
    [self.webView goForward];
}

- (BOOL)canForward{
    return self.webView.canGoForward;
}

#pragma mark - PULL&REFRESH
- (void)setPullToRefreshWithStyle:(NSDictionary *)style{
    //用自己派生的scrollview替代
    MyScrollView *subView = [[MyScrollView alloc] initWithWebView:self.webView];
    subView.delegate = self;
    self.pullScro = subView;
    
    [self.webView removeFromSuperview];
    [subView addSubview:self.webView];
    [self.view addSubview:subView];//在原来webview和view之间加入一个subview
    
//    判断str1是否包含str2
    BOOL(^containString)(NSString *, NSString *) =^(NSString *str1, NSString *str2){
        
        BOOL result = YES;
        NSRange range = [str1 rangeOfString:str2];
        if (range.location == NSNotFound) {
            result =  NO;
        }
        
        return result;
    };
    
    NSString *support = [style objectForKey:@"support"];
    if (support && (NSNull *)support != [NSNull null]) {
        BOOL support_value = [support boolValue];
        //不支持下拉刷新功能
        if (!support_value) {
            if (self.pullScro) {
                //移除pullScro
                [self.webView removeFromSuperview];
                [self.pullScro removeFromSuperview];
                [self.view addSubview:self.webView];
            }
            //恢复BSLWebView的bounces
            [self.webView.scrollView setBounces:((BSLWebView *)self.webView).shouldBounces];
            return;
        }
        
        else{
            [self.webView.scrollView setBounces:NO];//取消webview的回弹效果
        }
    }
    
    [subView setupPullContent];//设置下拉刷新控件
    
    NSString *height = [style objectForKey:@"height"];//窗口的下拉刷新控件高度
    if (height && (NSNull *)height != [NSNull null]) {
        CGFloat height_value = [height floatValue];
        if (containString(height, @"%")) {
            height_value = self.webView.height * height_value * 0.01;
        }
//        NSLog(@"%f",height_value);
        subView.label.height = height_value;
    }
    
    NSString *range = [style objectForKey:@"range"];//窗口可下拉拖拽的范围
    if (range && (NSNull *)range != [NSNull null]) {
        CGFloat range_value = [range floatValue];
        if (containString(range, @"%")) {
            range_value = self.webView.height * range_value * 0.01;
        }
        NSLog(@"%f",range_value);
        subView.maxPullDistance = range_value;
    }
    
    NSDictionary *contentdown = [style objectForKey:@"contentdown"];//在下拉可刷新状态时显示的内容
    if (contentdown && (NSNull *)contentdown != [NSNull null]) {
        NSString *contentdown_caption = contentdown[@"caption"];
//        NSLog(@"%@",contentdown_caption);
        subView.contentDown = contentdown_caption;
        [subView.label setText:contentdown_caption];
    }
    
    NSDictionary *contentover = [style objectForKey:@"contentover"];//在释放可刷新状态时显示的内容
    if (contentover && (NSNull *)contentover != [NSNull null]) {
        NSString *contentover_caption = contentover[@"caption"];
         NSLog(@"%@",contentover_caption);
        subView.contentOver = contentover_caption;
    }
    
    NSDictionary *contentrefresh = [style objectForKey:@"contentrefresh"];//在正在刷新状态时显示的内容
    if (contentrefresh && (NSNull *)contentrefresh != [NSNull null]) {
        NSString *contentrefresh_caption = contentrefresh[@"caption"];
         NSLog(@"%@",contentrefresh_caption);
        subView.contentRefresh = contentrefresh_caption;
    }
}

//刷新时请求数据函数
- (void)refreshData{
    //发出通知，告诉前端下拉动画已经完毕，可以开始请求数据，更新ui之类的操作
    [[NSNotificationCenter defaultCenter] postNotificationName:BSLWebViewDidRefreshNotification object:self];
}

- (void)endPullToRefresh{
    __block MyScrollView *scr = (MyScrollView *)[self.webView superview];
    [UIView animateWithDuration:REFRESH_DURATION_DEFAULT animations:^{
        scr.contentOffset = CGPointMake(0, 0);
        scr.contentInset = UIEdgeInsetsZero;
    } completion:^(BOOL finished) {
        self.isLoading = NO;
    }];
}
#pragma mark - ANIMATION
- (void)prepareTransitionWithAnimation:(NSString *)animation duration:(NSNumber *)duration{
    NSString *animationType = kCATransitionMoveIn;
    NSString *directionType = kCATransitionFromRight;
    
    if ([(NSNull *)animation isEqual:[NSNull null]] || [animation isEqualToString:@"none"]) {
        return;
    }
    
    else if ([animation isEqualToString:@"slide-in-right"]){
        directionType = kCATransitionFromRight;
    }
    
    else if ([animation isEqualToString:@"slide-in-left"]){
        directionType = kCATransitionFromLeft;
    }
    
    else if ([animation isEqualToString:@"slide-in-top"]){
        directionType = kCATransitionFromBottom;
    }
    
    else if ([animation isEqualToString:@"slide-in-bottom"]){
        directionType = kCATransitionFromTop;
    }
    
    else if ([animation isEqualToString:@"fade-in"]){
        self.view.layer.opacity = 0;
        return;
    }
    
    else if ([animation isEqualToString:@"zoom-out"]){
        self.view.transform = CGAffineTransformMakeScale(0.01f, 0.01f);
        return;
    }
    
    else if ([animation isEqualToString:@"zoom-fade-out"]){
        self.view.opaque = 0;
        self.view.transform = CGAffineTransformMakeScale(0.01f, 0.01f);
        return;
    }
    
    else if ([animation isEqualToString:@"pop-in"]){
        animationType = kCATransitionPush;
    }
    
    NSTimeInterval time = 0.3;
    if (![(NSNull *)duration isEqual:[NSNull null]]) {
        time = [duration floatValue]*0.001;
    }
    
    CATransition *ani = [CATransition animation];
    ani.delegate = self;
    [ani setType:animationType];
    [ani setSubtype:directionType];
    [ani setDuration:time];
    [self.view.layer addAnimation:ani forKey:@"showAni"];
}

- (void)animating:(NSString *)animation duration:(NSTimeInterval )duration{
    if (![(NSNull *)animation isEqual:[NSNull null]] &&
        ([animation isEqualToString:@"zoom-out"] ||
         [animation isEqualToString:@"fade-in"]  ||
         [animation isEqualToString:@"zoom-fade-out"])) {
            
            [UIView animateWithDuration:duration animations:^{
                
                if ([animation isEqualToString:@"zoom-out"]) {
                    self.view.transform = CGAffineTransformMakeScale(1.0, 1.0);
                }
                
                else if ([animation isEqualToString:@"fade-in"]){
                    self.view.layer.opacity = 1;
                }
                
                else if ([animation isEqualToString:@"zoom-fade-out"]){
                    self.view.layer.opaque = 1;
                    self.view.transform = CGAffineTransformMakeScale(1.0, 1.0);
                }
                
            } completion:^(BOOL finished) {
                [[NSNotificationCenter defaultCenter] postNotificationName:BSLWebViewDidShowNotification object:self];
            }];
        }
    
    else if ([self.view.layer animationKeys].count){
        [[NSNotificationCenter defaultCenter] postNotificationName:BSLWebViewDidShowNotification object:self];
    }
    
    else if ([animation isEqualToString:@"none"]){
        [[NSNotificationCenter defaultCenter] postNotificationName:BSLWebViewDidShowNotification object:self];
    }
}

- (void)closeViewAnimation:(NSString *)animation duration:(NSTimeInterval)duration{
    UIViewController *parentVC = [self parentViewController];
    if (parentVC) {
        //        NSLog(@"%@",[parentVC childViewControllers]);
        //        NSLog(@"%@",[parentVC.view subviews]);
        if ([(NSNull *)animation isEqual:[NSNull null]] || [animation isEqual:@"none"]) {
            //            [self.view removeFromSuperview];
            //            [self removeFromParentViewController];
            [[NSNotificationCenter defaultCenter] postNotificationName:BSLWebViewDidCloseNotification object:self];
        }
        
        else{
            [self dismissAnimating:animation duration:duration isHide:NO];
        }
    }
}

- (void)hideView:(NSString *)animation duration:(NSTimeInterval)duration{
    //self.currentVC.view
    UIViewController *parentVC = [self parentViewController];
    if (parentVC) {
        //        NSLog(@"%@",[parentVC childViewControllers]);
        //        NSLog(@"%@",[parentVC.view subviews]);
        if ([(NSNull *)animation isEqual:[NSNull null]] || [animation isEqual:@"none"]) {
            [self.view setHidden:YES];
            [[NSNotificationCenter defaultCenter] postNotificationName:BSLWebViewDidHideNotification object:self];
        }
        
        else{
            
            [self dismissAnimating:animation duration:duration isHide:YES];
        }
    }
    
}
- (void)dismissAnimating:(NSString *)animation duration:(NSTimeInterval)duration isHide:(BOOL)isHide{
    
    CGRect originalFrame= self.view.frame;
    [UIView animateWithDuration:duration animations:^{
        if ([animation isEqualToString:@"slide-out-right"]) {
            self.view.left = _screenWidth;
        }
        
        else if ([animation isEqualToString:@"slide-out-left"]) {
            self.view.right = 0;//slide-out-top
        }
        
        else if ([animation isEqualToString:@"slide-out-top"]) {
            self.view.bottom = 0;
        }
        
        else if ([animation isEqualToString:@"slide-out-bottom"]) {
            self.view.top = _screenHeight;
        }
        
        else if ([animation isEqualToString:@"fade-out"]) {
            self.view.layer.opacity = 0;
        }
        
        else if ([animation isEqualToString:@"zoom-in"]) {
            self.view.transform = CGAffineTransformMakeScale(0.01f, 0.01f);
        }
        
        else if ([animation isEqualToString:@"zoom-fade-in"] || [animation isEqualToString:@"zoom-in"]) {
            self.view.layer.opacity = 0;
            self.view.transform = CGAffineTransformMakeScale(0.01f, 0.01f);
        }
        
        else if ([animation isEqualToString:@"pop-out"]) {
            //TODO
            NSLog(@"pop-out 动画还未实现");
        }
        
    } completion:^(BOOL finished) {
        if (isHide){
            //TODO
            [self.view setHidden:YES];
            self.view.transform = CGAffineTransformMakeScale(1.0, 1.0);
            [self.view setFrame:originalFrame];
            [self.view.layer setOpacity:1];
            [[NSNotificationCenter defaultCenter] postNotificationName:BSLWebViewDidHideNotification object:self];
        }
        
        else{
            //            [self.view removeFromSuperview];
            //            [self removeFromParentViewController];
            [[NSNotificationCenter defaultCenter] postNotificationName:BSLWebViewDidCloseNotification object:self];
        }
    }];
}

#pragma mark - Delegate
#pragma UIWebViewDelegate
//- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{
//    
//    return [super webView:webView shouldStartLoadWithRequest:request navigationType:navigationType];
//}

- (void)webViewDidStartLoad:(UIWebView *)webView{
    
//    [((BSLWebView *)self.webView).browserView setHidden:NO];
    [[NSNotificationCenter defaultCenter] postNotificationName:BSLWebViewLoadingNotification object:self];
    [super webViewDidStartLoad:webView];
}

- (void)webViewDidFinishLoad:(UIWebView *)webView{
    if (webView) {
        [((BSLWebView *)webView).browserView setOpaque:YES];
        [((BSLWebView *)webView).browserView setHidden:NO];
    }
    
    if (webView && !((BSLWebView *)self.webView).shouldScale) {
        //禁止缩放
        NSString *meta = @"document.getElementsByName(\"viewport\")[0].content = \"width= device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no\"";
        [self.webView stringByEvaluatingJavaScriptFromString:meta];
    }
    //    self.webView.backgroundColor =
    if (!webView.isLoading) {
        if ([[webView superview] isKindOfClass:[MyScrollView class]]) {
            ((MyScrollView *)[webView superview]).contentSize = CGSizeMake(webView.scrollView.contentSize.width, webView.scrollView.contentSize.height);
        }
        
        [[NSNotificationCenter defaultCenter] postNotificationName:BSLWebViewDidLoadNotification object:self];
    }
    
    [super webViewDidFinishLoad:webView];
}

- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error{
    //NSURLErrorCancelled
    if (!webView.isLoading) {
        [[NSNotificationCenter defaultCenter] postNotificationName:BSLWebViewDidFailLoadNotification object:self];
    }
    
    [super webView:webView didFailLoadWithError:error];
}

#pragma UIScrollViewDelegate

- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
//    NSLog(@"scrollView:%@",scrollView);
    
    BSLWebView *webView = (BSLWebView *)self.webView;
    if (webView.bounceBackgroundView && scrollView.contentOffset.y <= - K_DEFAULT_BOUNCE_BG_HEIGHT) {
        webView.bounceBackgroundView.height = -scrollView.contentOffset.y;
        webView.bounceBackgroundView.bottom = 0;
    }
    
    //下拉刷新
    if ([scrollView isKindOfClass:[MyScrollView class]] && !self.isLoading && scrollView.contentOffset.y <= -OFFSET_Y_OVER_DEFAULT) {
        MyScrollView *scrV = (MyScrollView *)scrollView;
        [scrV.label setText:scrV.contentOver];
        self.shouldLoad = YES;
    }
    
    else if ([scrollView isKindOfClass:[MyScrollView class]] && !self.isLoading){
        MyScrollView *scrV = (MyScrollView *)scrollView;
        [scrV.label setText:scrV.contentDown];
        self.shouldLoad = NO;
    }
    
//    NSLog(@"%@",NSStringFromCGPoint(scrollView.contentOffset));
}
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{
//    NSLog(@"%@",NSStringFromCGPoint(scrollView.contentOffset));
    //当试图从顶部移除界面时，滚动效果由webview实现
    BOOL scrollEnabled = (scrollView.contentOffset.y < 0 ) ? NO : YES;
    self.webView.scrollView.scrollEnabled = scrollEnabled;
}

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{
    
    if (self.shouldLoad && [scrollView isKindOfClass:[MyScrollView class]]) {
        self.isLoading = YES;
        MyScrollView *scrV = (MyScrollView *)scrollView;
        
        [UIView animateWithDuration:REFRESH_DURATION_DEFAULT animations:^{
            scrV.shouldSetOffset = NO;//防止回弹动画执行之前，突然回滚到refreshingHeight的bug
            scrV.contentOffset = CGPointMake(0, -scrV.refreshingHeight);
            scrV.contentInset = UIEdgeInsetsMake(scrV.refreshingHeight, 0, 0, 0);
            scrV.shouldSetOffset = YES;
            
        } completion:^(BOOL finished) {
            [scrV.label setText:scrV.contentRefresh];
            [self refreshData];
        }];
    }
}

#pragma CAAnimation
- (void)animationDidStart:(CAAnimation *)anim{
    
}

- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{
    
}
@end
